<template>
  <div class="views" id="views" @touchmove.prevent @mousewheel.prevent>
    <div id="containerJplbs" class="container"></div>
  </div>
</template>

<script>
import * as THREE from 'three/build/three.module'
import { ThreeJsUtil } from '@/assets/ThreeJsUtil/ThreeJsUtil'
import { MqttUtil } from '@/utils/MqttUtil'

const threeApp = new ThreeJsUtil()
export default {
  props: ['home'],
  data () {
    return {
      params: {
        methods: {
          animation: false,
          renderer: true,
          light: true,
          controls: true,
          TWEEN: true,
          postprocessing: true,
          statement: true
        },
        events: {
          windowResize: true
        },
        params: {
          containerId: 'containerJplbs',
          renderer: [
            'WebGLRenderer'
          ],
          controls: [
            'OrbitControls'
          ],
          rendererParams: {
            antialias: true
          },
          postprocessing: [
            'OutlinePass',
            // 'UnrealBloomPass'
          ]
        }
      },
      topics: {
        pcj: `${this.$route.path}_position-controls-json`,
        soj: `${this.$route.path}_select-objName-json`,
        poj: `${this.$route.path}_perform-objName-json`
      },
      routerName: this.$route.name,
      lightGroup: ['Group002'],
      lightMesh: ['Object001'],
      lightObj: []
    }
  },
  mounted () {
    this.home.loading()
    /**
     * 初始化场景
     */
    threeApp.init(this.params, (scene, camera, renderer) => {
      // 重设相机初始位置
      camera.position.set(-1, 0.1, 0)

      threeApp.orbitControls.autoRotate = false
      threeApp.orbitControls.enableZoom = false
      threeApp.orbitControls.enablePan = false

      // // 设置辉光参数
      // threeApp.unrealBloomPass.threshold = 0
      // threeApp.unrealBloomPass.strength = 0.5
      // threeApp.unrealBloomPass.radius = 0
    })

    threeApp.addModel({
      url: 'static/model/fbx/torch/tsjs/jplbs.FBX',
      type: 'fbx',
      name: 'jplbs'
    }, (obj) => {
      obj.position.set(1000, -300, 1500)
      obj.scale.set(0.4, 0.4, 0.4)
      this.home.loadOver()

      obj.traverse((child) => {
        if (this.lightMesh.indexOf(child.name) > -1) {
          child.nextMaterial = child.material
          child.material = new THREE.MeshStandardMaterial({
            color: '#746e6e',
            transparent: true,
            opacity: 1
          })
          this.lightObj.push(child)
        }
      })

      // 添加双击事件
      threeApp.addOn(threeApp.scene, 'dblclick', (objList) => {
        const obj = objList[0].object

        // console.log(obj.name, obj.parent.name)
        this.performEvent(obj)
      }, 'dblclick_jplbs', {
        recursive: true
      })

      // 添加鼠标移动事件
      threeApp.addOn(threeApp.scene, 'mousemove', (objList) => {
        const obj = objList[0].object

        // threeApp.outlinePass.selectedObjects = [obj]
        this.selectEvent(obj)
      }, 'mousemove_jplbs', {
        recursive: true
      }, () => {
        threeApp.outlinePass.selectedObjects = []
        this.curentObjName = null
        this.mqttPubSelectObjName('null')
      })

      // 添加触摸事件
      threeApp.addOn(threeApp.scene, 'touchstart', (objList) => {
        const obj = objList[0].object
        const group = obj.parent

        if (obj.name === this.curentObjName || group.name === this.curentGroupName) { // 判断为双击
          this.performEvent(obj)
        } else { // 判断为单击
          this.selectEvent(obj)
        }
      }, 'touchstart_jplbs', { recursive: true }, () => {
        threeApp.outlinePass.selectedObjects = []
        this.curentObjName = null
        this.curentGroupName = null
        this.mqttPubSelectObjName('null')
      })
    }, (progress) => {
      progress = parseInt((progress.loaded / progress.total) * 100)
      this.home.loadProgress(progress)
    })

    threeApp.animate(() => {
      this.mqttPubPositionControls()
    })
    this.mqttInit()
  },
  methods: {
    mqttInit () {
      if (this.home.mqttForm.status === 'sub') {
        if (this.mqtt) this.mqtt.client.end()
        this.mqtt = new MqttUtil(`mqtt://${this.home.mqttForm.url}`, { clientId: `${this.$route.name}_${this.home.mqttForm.status}` })
        this.mqtt.setSubTopic(this.topics.pcj)
        this.mqtt.setSubTopic(this.topics.soj)
        this.mqtt.setSubTopic(this.topics.poj)
        this.mqttSubInit()
        this.mqtt.subTopic(this.mqttSub)
      } else if (this.home.mqttForm.status === 'pub') {
        if (this.mqtt) this.mqtt.client.end()
        this.mqtt = new MqttUtil(`mqtt://${this.home.mqttForm.url}`, { clientId: `${this.$route.name}_${this.home.mqttForm.status}` })
      } else if (this.home.mqttForm.status === 'alone') {
        if (this.mqtt) this.mqtt.client.end()
        this.mqttSubDestroy()
      }
    },
    mqttSubInit () {
      threeApp.orbitControls.enabled = false
    },
    mqttSub (topic, message) {
      message = JSON.parse(message.toString())
      if (topic === this.topics.pcj && message) {
        threeApp.camera.position.set(...message.position)
        threeApp.camera.lookAt(...message.controls)
      } else if (topic === this.topics.soj && message) {
        if (message.objName !== 'null') {
          const obj = threeApp.scene.getObjectByName(message.objName)
          this.selectEvent(obj)
        } else {
          threeApp.outlinePass.selectedObjects = []
        }
      } else if (topic === this.topics.poj && message) {
        const obj = threeApp.scene.getObjectByName(message.objName)
        this.performEvent(obj)
      }
    },
    mqttSubDestroy () {
      threeApp.orbitControls.enabled = true
    },
    mqttPubPositionControls () {
      if (this.home.mqttForm.status !== 'pub' || !this.mqtt || this.$route.name !== this.routerName) return
      const controls = [threeApp.orbitControls.target.x, threeApp.orbitControls.target.y, threeApp.orbitControls.target.z]
      const position = [threeApp.camera.position.x, threeApp.camera.position.y, threeApp.camera.position.z]

      const message = JSON.stringify({
        position,
        controls
      })
      if (this.nextPCMessage === message) return
      this.nextPCMessage = message
      this.mqtt.pubTopic(this.topics.pcj, message)
    },
    mqttPubSelectObjName (objName) {
      if (this.home.mqttForm.status !== 'pub' || !this.mqtt || this.$route.name !== this.routerName) return
      const message = JSON.stringify({
        objName
      })
      this.mqtt.pubTopic(this.topics.soj, message)
    },
    mqttPubPerformObjName (objName) {
      if (this.home.mqttForm.status !== 'pub' || !this.mqtt || this.$route.name !== this.routerName) return
      const message = JSON.stringify({
        objName
      })
      this.mqtt.pubTopic(this.topics.poj, message)
    },
    selectEvent (obj) {
      switch (obj.name) {
      }
      const group = obj.parent
      switch (group.name) {
        case 'Group160':
        case 'ggg':
        case 'ggg001':
        case 'ggg002':
          threeApp.outlinePass.selectedObjects = [group]
          this.curentGroupName = group.name
          this.mqttPubSelectObjName(obj.name)
          return
      }
      for (var i in this.lightMesh) {
        const item = this.lightMesh[i]
        if (item === obj.name) {
          threeApp.outlinePass.selectedObjects = [obj]
          this.curentObjName = obj.name
          this.mqttPubSelectObjName(obj.name)
          return
        }
      }
      threeApp.outlinePass.selectedObjects = []
      this.curentObjName = null
      this.curentGroupName = null
      this.mqttPubSelectObjName('null')
    },
    performEvent (obj) {
      threeApp.outlinePass.selectedObjects = []
      this.curentObjName = null
      this.curentGroupName = null
      this.mqttPubSelectObjName('null')
      switch (obj.name) {
      }
      const group = obj.parent
      switch (group.name) {
        case 'Group160':
          this.home.setPanel('screenPanel')
          this.mqttPubPerformObjName(obj.name)
          return
        case 'ggg':
        case 'ggg001':
        case 'ggg002':
          this.home.setPanel('cameraPanel')
          this.mqttPubPerformObjName(obj.name)
          return
      }

      for (var i in this.lightMesh) {
        const item = this.lightMesh[i]
        if (item === obj.name) {
          this.lightObj.forEach((mesh) => {
            const currentLightColor = mesh.material
            mesh.material = mesh.nextMaterial
            mesh.nextMaterial = currentLightColor
          })
          this.home.setPanel('lampPanel')
          this.mqttPubPerformObjName(obj.name)
          return
        }
      }
    },
    openLedVideo (videoDom) {
      const obj = threeApp.scene.getObjectByName('Obj3d66-732493-1-683')
      const texture = new THREE.VideoTexture(videoDom)

      // texture.wrapS = texture.wrapT = THREE.RepeatWrapping // 重复
      texture.wrapS = texture.wrapT = THREE.ClampToEdgeWrapping // 平铺拉伸
      texture.minFilter = THREE.LinearFilter
      texture.magFilter = THREE.LinearFilter
      texture.format = THREE.RGBFormat

      if (obj.currentVideoMaterial) obj.currentVideoMaterial = null
      obj.currentVideoMaterial = obj.material
      obj.material = new THREE.MeshBasicMaterial({ map: texture })
    },
    closeLedVideo () {
      const obj = threeApp.scene.getObjectByName('Obj3d66-732493-1-683')

      obj.material = obj.currentVideoMaterial
      obj.currentVideoMaterial = null
    }
  },
  beforeDestroy () {
    threeApp.rmOn('dblclick', 'dblclick_jplds')
    threeApp.rmOn('mousemove', 'mousemove_jplds')
    threeApp.rmOn('touchstart', 'touchstart_jplds')
    threeApp.destroy()
    if (this.mqtt) this.mqtt.client.end()
  }
}
</script>

<style scoped>
.views {
  height: 100%;
  width: 100%;
}

.container {
  height: 100%;
  width: 100%;
}
</style>
